package com.voice.call.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import voice.voice.call.cache.ConfigVosAccountCache;

import com.voice.call.common.Const;
import com.voice.call.entity.UserInfo;
import com.voice.call.entity.VosAccount;
import com.voice.call.service.UserInfoService;
import com.voice.call.service.VosService;
import com.voice.call.utils.HttpTransport;
import com.voice.call.utils.JSONUtil;
import com.voice.call.utils.StringUtil;



@Service
public class VosServiceImpl implements VosService{
	
	private static final Logger log = LoggerFactory.getLogger(VosServiceImpl.class);
	
	private static final String ret_code_key = "retCode";
	private static final String ret_code_success = "0";
	private static final String ret_exist_code = "-10004";
	
	
	private static final Map<String,String> postHeaders = new HashMap<String,String>();
	
	static{
		postHeaders.put("Content-Type", "text/html;charset=UTF-8");
		postHeaders.put("Accept", "application/json");
	}

	
	@Resource
	private Properties configProperties;
	
	
	@Resource
	private UserInfoService userInfoService;
	
	@Resource
	private ConfigVosAccountCache configVosAccountCache;
	
	
	//获取vos帐号
	@Override
	public	Map<String, Object> getVosAccount(VosAccount acct,String phone,String displayNumber){
		
		//VosAccount acct = configVosAccountCache.getDefaultVosAccount();
		
		Map<String, Object> vosMap =new  HashMap<String, Object>();
		String accout = "",pwd = "";
		Map<String,Object> phoneMap = this.queryPhone(acct,acct.getVosPrefix()+phone,displayNumber);
		//log.info("phoneMap ={}",JSONUtil.mapToJson(phoneMap));
		if (phoneMap!=null) {
			accout = phoneMap.get("e164").toString();
			pwd = phoneMap.get("password").toString();
		}else{
			phoneMap = new HashMap<String, Object>();
			if (this.createPhone(acct,phone, phoneMap,displayNumber)) {
				accout = phoneMap.get("vos_account").toString();
				pwd = phoneMap.get("vos_pwd").toString();
			}
		}
		
		vosMap.put("vos_account", accout);
		vosMap.put("vos_pwd", pwd);
		vosMap.put("server_ip", acct.getServerIp());
		
		return vosMap;
		
	}

	@Override
	public boolean createPhone(VosAccount acct,String phone,Map<String,Object> phoneMap,String displayNumber){
		
		try{
			
			//VosAccount acct = configVosAccountCache.getDefaultVosAccount();
			
			if(acct == null){
				log.info("未配置vos帐号");
				return false;
			}
			
			//String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/CreatePhone";
			//String vos_account = configProperties.getProperty(Const.VOS_ACCOUNT);
			String vos_url = acct.getVosUrl()+"external/server/CreatePhone";
			String vos_account = acct.getVosAccount();
			log.info("vos创建用户请求地址:{}",vos_url);
			Map<String,Object> bodyMap=new HashMap<String,Object>();
			bodyMap.put("autoCreateAccount", false);
			bodyMap.put("e164", String.format("%s%s", acct.getVosPrefix(),phone));
			bodyMap.put("account", vos_account);
			bodyMap.put("password", StringUtil.buildRandomCode(8));
			if (!StringUtil.isEmpty(displayNumber)) {
				bodyMap.put("displayNumber", displayNumber);//去电显示
			}else {
				bodyMap.put("displayNumber", acct.getDisplayNumber());//去电显示
			}
			//bodyMap.put("callLevel", 4);//国内长途
			bodyMap.put("callLevel", 5);//国际长途
			bodyMap.put("feerateGroup", acct.getFeerateGroup());
			bodyMap.put("rewriteRulesOutCallee", acct.getRule());//呼出被叫改写规则，需符合改写规则书写格式
			bodyMap.put("lineCapacity", acct.getLineCapacity());//同时呼叫数限制

			String bodyData = JSONUtil.mapToJson(bodyMap);
			log.info("vos创建用户请求参数:{}",bodyData);
			
		
			
			String jsonStr = HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
					//HttpTransport.getInstance().doJSONPost(vos_url, bodyData);
			log.info("vos创建用户请求结果:{}",jsonStr);
			if(jsonStr == null){
				log.error("创建 vos帐户失败!");
				return false;
			}
			Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
			
			if(resultMap != null && resultMap.get(ret_code_key) !=null){
				
				//修改用户资料
				//sbPwd.append(bodyMap.get("password").toString());
				
				if(resultMap.get(ret_code_key).toString().equals(ret_code_success)){
					log.info("创建 vos帐户成功!");
					if(phoneMap!=null){
						phoneMap.put("vos_account", bodyMap.get("e164"));
						phoneMap.put("vos_pwd", bodyMap.get("password"));
					}
					return true;
				}
				else if(resultMap.get(ret_code_key).toString().equals(ret_exist_code)){
					log.info("创建 vos帐户已存在!");
					Map<String, Object> queryMap = this.queryPhone(acct,bodyMap.get("e164").toString(),displayNumber);
					if(phoneMap!=null&&queryMap!=null){
						phoneMap.putAll(queryMap);
					}
					return true;
				}else {
					
				}
				
				
				
				
			}
			log.error("创建 vos帐户失败!");
			return false;
			
		}catch(Exception ex){
			ex.printStackTrace();
			log.error("创建vos帐户发生异常");
			return false;
		}
		
		
		
	}
	
	@Override
	public boolean deletePhone(VosAccount acct,String phone){
		
		try{
			
			//VosAccount acct = configVosAccountCache.getDefaultVosAccount();
			
			String vos_url = acct.getVosUrl()+"external/server/DeletePhone";
			String bodyData = "{\"e164\":\""+phone+"\"}";
			String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
			if(jsonStr == null){
				log.error("删除话机异常!");
				return false;
			}
			Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
			if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
				return true;
			}
			return false;
			
		}catch(Exception ex){
			ex.printStackTrace();
			log.error("删除话机发生异常");
			return false;
		}
		
		
	}
	
	//修改显示号码
	@Override
	public	boolean modifyDisplayNumber(String account,String displayNumber){
		try {
			
			VosAccount acct = configVosAccountCache.getDefaultVosAccount();
			String vos_url = acct.getVosUrl()+"external/server/ModifyPhone";
			String bodyData = "{\"account\":\""+acct.getVosAccount()+"\",\"e164\":\""+account+"\",\"displayNumber\":\""+displayNumber+"\"}";
			String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
			log.info("修改手机号码请求结果:{}",jsonStr);
			if(jsonStr == null){
				log.error("修改显示号码异常!");
				return false;
			}
			Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
			if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
				return true;
			}
			return false;
			
		} catch (Exception e) {
			e.printStackTrace();
			log.error("修改显示号码请求发生异常");
			return false;
		}
		
		
		
	}
	
	//查询话机
	@SuppressWarnings("unchecked")
	@Override
	public Map<String,Object> queryPhone(VosAccount acct,String phone,String displayNumber){
		
		try{
			
			//VosAccount acct = configVosAccountCache.getDefaultVosAccount();
			if(acct == null){
				log.info("未配置vos帐号");
				return null;
			}
			
			String vos_account = acct.getVosAccount();
	        String vos_url = acct.getVosUrl()+"external/server/GetPhone";
		
			//String vos_account = configProperties.getProperty(Const.VOS_ACCOUNT);
	        //String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/GetPhone";
	        
	        log.info("查询话机url:{}",vos_url);
			
			Map<String,Object> bodyMap=new HashMap<String,Object>();
			bodyMap.put("e164s", new String[]{phone});
			bodyMap.put("accounts", new String[]{vos_account});
		
			String bodyData = JSONUtil.mapToJson(bodyMap);
			log.info("查询话机请求参数:{}",bodyData);
			String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
			//log.info("查询话机请求结果:{}",jsonStr);
			if(jsonStr == null){
				log.error("查询话机请求结果失败!");
				return null;
			}
			Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
			if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
				
				ArrayList<Map<String,Object>> list= (ArrayList<Map<String,Object>>)resultMap.get("infoPhones");
				if(list!=null && !list.isEmpty()){
					
					Map<String,Object> rsMap = list.get(0);
					/****************修改显示号码开始 displayNumber 是否修改显示号码*****************/ 
					log.info("需要修改显示号码:{}",displayNumber);
					if (!StringUtil.isEmpty(displayNumber)) {
						if (rsMap.get("displayNumber")!=null) {
							String curDisplay = rsMap.get("displayNumber").toString();
							log.info("当前显示号码为:{}",curDisplay);
							if (!curDisplay.equals(displayNumber)) {
								this.modifyDisplayNumber(phone, displayNumber);
							}
						}
					}
					/**********修改显示号码结束************/ 
					
				   return rsMap;
				}
			}
			return null;
		
		}catch(Exception ex){
			ex.printStackTrace();
			log.error("查询话机发生异常");
			return null;
		}
		
	}
	
	//在线话机
	@SuppressWarnings("unchecked")
	@Override
	public List<String> queryPhoneOnline(String[] phones){
		
		String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/GetPhoneOnline";
		Map<String,Object> bodyMap=new HashMap<String,Object>();
		bodyMap.put("e164s", phones);
		
		String bodyData = JSONUtil.mapToJson(bodyMap);
		String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
		Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
		if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
			
			
			ArrayList<Map<String,Object>> list= (ArrayList<Map<String,Object>>)resultMap.get("infoPhoneOnlines");
			if(list!=null && !list.isEmpty()){
				
				List<String> onlinePhones = new ArrayList<String>();
				
				for(Map<String,Object> item:list){
					onlinePhones.add((String)item.get("e164"));
				}
				
				return onlinePhones;
				
			}
			
		}
		return null;
	}
	
	@Override
	public String[] GetAllPhoneOnline(){
		
		String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/GetAllPhoneOnline";
		
		String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, null);
		Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
		if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
			
			if(resultMap.get("e164s")!=null){
				
				return (String[])resultMap.get("e164s");
			}
		}
		return null;
	}
	
	@Override
	public boolean disconnectCall(String[] callIds){
		String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/DisconnectCurrentCall";
		Map<String,Object> bodyMap=new HashMap<String,Object>();
		bodyMap.put("callIds", callIds);
		
		String bodyData = JSONUtil.mapToJson(bodyMap);
		String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
		Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
		if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
			return true;
		}
		return false;
	}
	
	//清空无用话机
	@Override
	public	void clearUnTelephone(VosAccount acct){

		//VosAccount acct = configVosAccountCache.getDefaultVosAccount();
		if(acct==null){
			log.info("清空无用话机时，未配置vos帐户");
			return;
		}
		//List<UserInfo> list = userInfoService.getUnTelephoneList(acct.getVosPrefix());
		List<UserInfo> list = userInfoService.getUnTelephoneList(acct);
		if(list!=null && !list.isEmpty()){
			
			for (UserInfo userInfo : list) {
				String phoneString = String.format("%s%d", acct.getVosPrefix(),userInfo.getId());
				this.deletePhone(acct,phoneString); //删除话机
			}
			
		}
		
	}
	
	//查询话机是否存在
	@SuppressWarnings("unchecked")
	private boolean existPhone(String phone,String vos_account){
		
		if(vos_account == null){
			vos_account = configProperties.getProperty(Const.VOS_ACCOUNT);
		}
		
		String vos_url = configProperties.getProperty(Const.VOS_URL)+"external/server/GetPhone";
		
		Map<String,Object> bodyMap=new HashMap<String,Object>();
		bodyMap.put("e164s", new String[]{phone});
		bodyMap.put("accounts", new String[]{vos_account});
		
		String bodyData = JSONUtil.mapToJson(bodyMap);
		String jsonStr =HttpTransport.getInstance().doPost(vos_url, postHeaders, bodyData);
		Map<String,Object> resultMap = JSONUtil.jsonToMap(jsonStr);
		if(resultMap != null && resultMap.get(ret_code_key) !=null && resultMap.get(ret_code_key).toString().equals(ret_code_success)){
			
			ArrayList<Map<String,Object>> list= (ArrayList<Map<String,Object>>)resultMap.get("infoPhones");
			if(list!=null && !list.isEmpty()){
				return true;
			}
		}
		return false;
	}
	
	
}
